
package dyyx.util;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.StringUtils;


/**
 * 性能压测或日常运行时  性能相关数据对象 接口响应时间 消息积压  连接池等信息
 * 
 * @author dugang 2017-12-05 15:37:00
 */
public class RunStatus {
	
	
	public final String VERSION = "2017-12-05 15:39:00";
		
	/**
	 * 忽略 RiskDimensionStatistic 否则内存会爆
	 */
	public boolean ignoreRiskDimStat = true;
	
	public static final Date startTime = new Date();
	/**
	 * 加入版本控制 确认部署代码是否ok
	 */
	public boolean debug = false;
	
	public final String defaultCharset = Charset.defaultCharset().name();
	
	
	
	public long resetTime;

	
	
	public final Map<String,String> infoMap = new ConcurrentHashMap<String,String>();
	
	public final Map<String,String> staticInfoMap = new ConcurrentHashMap<String,String>();

	
	public final Map<String,AtomicLong> countMap = new ConcurrentHashMap<String,AtomicLong>();
	
	/**
	 * 通用的打点数据 不需要定义字段 根据 key 区分
	 */
	public final Map<String,TimeInfo> timeInfoMap = new ConcurrentHashMap<String,TimeInfo>();
	
	
	private final int ERRORS_LEN = 100;
	private final String[] errors = new String[ERRORS_LEN];
	private final AtomicLong errorSeq = new AtomicLong(0);
	
	
	
	public synchronized void reset(){
	
		timeInfoMap.clear();
		infoMap.clear();
		countMap.clear();
		
		for(int i=0;i<ERRORS_LEN;i++){
			errors[i] = null;
		}
		
		resetTime = System.currentTimeMillis();
		
	}
	
	
	
	public void updateInfo(String key,String msg){
		if(StringUtils.isBlank(key) || StringUtils.isBlank(msg)){
			return;
		}
		infoMap.put(key,msg);
	}
	
	public void updateStaticInfo(String key,String msg){
		if(StringUtils.isBlank(key) || StringUtils.isBlank(msg)){
			return;
		}
		staticInfoMap.put(key,msg);
	}
	
	
	
	public String getResetTimeStr(){
		if(resetTime<=0){
			return null;
		}
		return CommUtil.getDateString(new Date(resetTime));
	}
	
	public String getStartTimeStr(){
		return CommUtil.getDateString(startTime);
	}
	
	public void updateCount(String key,long delta){
		if(delta<=0){
			return;
		}
		AtomicLong al = countMap.get(key);
		if(al==null){
			al = new AtomicLong(0);
			countMap.put(key,al);
		}
		if(delta==1){
			al.incrementAndGet();
		}else{
			al.addAndGet(delta);
		}
		
	}
	
    public void updateCount(String key){
    	updateCount(key,1);
	}
    
    
    public void logError(String tag,Throwable e){
    	int index = fetchErrorInfoIndex();
    	Date now = new Date();
    	if(tag==null){
    		tag = "0";
    	}
    	errors[index] = now.getTime()+":"+tag+":"+e+":"+now;
    }

    private int fetchErrorInfoIndex(){
    	
    	long tmp = errorSeq.getAndIncrement();
    	int inttmp = (int) (tmp % ERRORS_LEN);
    	if(inttmp<0){
    		inttmp = 0 - inttmp;
    	}    	
    	return inttmp;
    }
    
    public List<String> getErrorList(){
    	List<String> list = new ArrayList<String>();
        for(String item:errors){
        	if(StringUtils.isBlank(item)){
        		continue;
        	}
        	list.add(item);
        }
    	Collections.sort(list);
    	Collections.reverse(list);
    	return list;
    }

	public boolean isDebug() {
		return debug;
	}

	public void setDebug(boolean debug) {
		this.debug = debug;
	}


}
